package interfaz_movimiento;
import interfaces.AgentInterface;


import interfaces.impl.Agent;
import interfaces.impl.HumanInteraction;


import java.awt.Color;

import java.awt.Graphics2D;


import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import javax.naming.spi.ObjectFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;



import objects.WorldObject;
import factory.*;

import personajes_movimiento.Jugador;
import universe.*;
import eventos.EventInfObjectBar;
import eventos.ObjectBarClickedListener;
import eventos.ObjectBarEvent;
import extra.Position;






public class PaintPanel extends JPanel implements Runnable , ObjectBarClickedListener{
	
	
	private ArrayList<WorldObject> imagesList;
	
	private Jugador jugador;
	private Universe world;
	
	//graphic to paint pixels  not free  
	private Graphics graph;
	private BufferedImage image;
	private int freeColor;

	private int dx=0,dy=0;
	
	private int width=400;

	private int height=400;
	
	private int state = Constants.WAIT_FOR_ACTION;
	private PopUpInteraction popUp; 
	private JFrame frame;
	
	public PaintPanel(JFrame frame){
		this.frame=frame;
		setVisible(true);
		
		jugador = new Jugador();
		world =  new Universe(1, 1);
		
		//createCollitionBuffer();
		
		addMouseListener(new mouseListener());
		addMouseMotionListener(new mouseMotionListener());
		
		popUp=new PopUpInteraction();
		
	}
	
	/*private void createCollitionBuffer(){
		image = new BufferedImage(world.getWidth()*Constants.BOX_WIDTH, world.getHeight()*Constants.BOX_HEIGHT, BufferedImage.TYPE_INT_RGB);
		graph= image.createGraphics();
		graph.setColor(new Color(237,2,53));
		graph.fillRect(0, 0, world.getWidth(), world.getHeight());
		freeColor=image.getRGB(10, 10);
	}*/
	
	@Override
	public void paint(Graphics g) {
		
		
		g.clearRect(0, 0, world.getScreenWidth(), world.getScreenHeight());
		
		
		Graphics2D g2d = (Graphics2D) g;
		AffineTransform prev = g2d.getTransform();
		AffineTransform at =prev;
		
		if((jugador.getX()+width/2)>=world.getScreenWidth()){
			
			if(width<world.getWidth()){
				dx=((width)-world.getScreenWidth());
			}
		}
		else{
			if(jugador.getX()>=(width/2) ){					
				dx=(width/2)-(jugador.getX());
			}
		}

		//PARA LAS Y
		
		if((jugador.getY()+height/2)>=world.getScreenHeight()){
			
			if(height<world.getScreenHeight()){
				dy=((height)-world.getScreenHeight());
			}
		}
		else{
			if(jugador.getY()>=(height/2) ){
				dy=(height/2)-(jugador.getY());
			}
		}
		
		at=AffineTransform.getTranslateInstance(dx,dy);
		g2d.setTransform(at);
		
		
			//world.paint(g);
			/*if(imagesList.contains(jugador.getWorldObject())){
				//aquei actualizo
			}*/
			world.paint(g2d);
			imagesList = world.getListObjectsToPaint();
			Collections.sort(imagesList);
			
			for(WorldObject obj : imagesList){
				obj.paint(g);
				for(AgentInterface agentDraw : obj.getListAgents()){
					agentDraw.paint(g, obj);
				}
			}

		
		
		g2d.setTransform(prev);
	
	}
	
	private class mouseMotionListener implements MouseMotionListener{

		@Override
		public void mouseDragged(MouseEvent ev) {
			// TODO Auto-generated method stub
			//jugador.calculatePositionTogo(ev.getX()-dx, ev.getY()-dy);
			
		}

		@Override
		public void mouseMoved(MouseEvent ev) {
			// TODO Auto-generated method stub
			
			
			//System.out.println("MEMoci "+ev.getX()+"  otro "+ev.getY());
		}
		
	}
	
	private class mouseListener implements MouseListener{

		@Override
		public void mouseClicked(MouseEvent ev) {
			
			switch(state){
			case Constants.WAIT_FOR_ACTION:
				if(ev.getButton() == MouseEvent.BUTTON3){
					System.out.println("Click izquierdo");
					WorldObject obj = world.clickObject(ev.getX()-dx,ev.getY()-dy);
					if(obj!=null){
						System.out.println("Click izquierdo1 "+obj.getPosition());
						showPopUp(ev.getX()-10,ev.getY()-10,obj);
						return;
					}
					
				}
				
			break;
				
				
			case Constants.PARAMETERS_FOR_ACTION:
				if(ev.getButton() == MouseEvent.BUTTON3){
					state=Constants.WAIT_FOR_ACTION;
					System.out.println("NO DOY PARAMETROS A LA ACCION");
					return;
				}
				System.out.println("Asigno Parametro");
				setParameter(ev.getX()-dx, ev.getY()-dy);
			break;
			}
	
		}

		@Override
		public void mouseEntered(MouseEvent ev) {
			
			
			//Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(miraImagen , new Point(10,10), "Mira");
			//setCursor(cursor);
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		
	}

	@Override
	public void run() {
		
			//era 20
		double dTime= System.currentTimeMillis();
		while(true){
			try {
				
				Thread.sleep(20);
				dTime = System.currentTimeMillis()-dTime;
				
				
				
				
				world.update(dTime);
				
				
				if(state==Constants.PARAMETERS_FOR_ACTION && popUp.getNumParameters()==0){
					makeAction();
					state=Constants.WAIT_FOR_ACTION;
				}
				
								
				dTime= System.currentTimeMillis();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			repaint();
			
		}
		
	}

	private void makeAction() {
		//before i have to send the parameters
		popUp.getHumanInteraction().setActive(true);
		popUp=new PopUpInteraction();
	}

	private void setParameter(int x, int y){
		if(popUp.getHumanInteraction().setParameter(new Position(x,y),world)){
			state=Constants.WAIT_FOR_ACTION;
		}
		
	}
	
	@Override
	public void changeObject(ObjectBarEvent event) {
		System.out.println("2"+event);
		EventInfObjectBar ev = (EventInfObjectBar) event.getSource();
 		
		
	}
	/*public void setWorldSize (int width, int height){
		world.setHeight(height);
		world.setWidth(width);
		
	}*/

	public void newWorld(int width, int height) {
		world = new Universe(width, height);
		//world.addObject(jugador.getWorldObject());
		//createCollitionBuffer();
		repaint();
		
	}

	public String save() {
		String save = new String();
			
		
		save = world.saveFile(save);
		
		return save;
	}

	public void load(String name) {
		world.loadFile(name);
		ArrayList<WorldObject> listObjects = new ArrayList<WorldObject>();
		for(WorldObject obj : world.getListObjects()){
			System.out.println("Estoy asignando imagenes de lo que carge "+obj.getObjectReference());
			double x = obj.getPosition().getX();
			double y = obj.getPosition().getY();
			obj = factory.ObjectFactory.createWorldObject(obj.getObjectReference(),new Position(x,y));
			double xMid =obj.getImageObject().getImageToShow().getWidth()/2;
			double yMid =obj.getImageObject().getImageToShow().getHeight()/2;
					
			obj.getImageObject().setPosition(new Position(x-xMid,y-yMid));
			obj.setPosition(new Position(x,y));
			listObjects.add(obj);
		}
		world.setListObjects(listObjects);
		imagesList = world.getListObjectsToPaint();
		//imagesList.add(jugador.getWorldObject());
		//createCollitionBuffer();
		System.out.println("Estoy as "+ world.getListObjects().get(0).getImageObject().getImageToShow().getWidth());
	}

	private void showPopUp(int x, int y, WorldObject obj) {
		System.out.println("Muestro popUp");
		popUp= new PopUpInteraction(obj,this);
		popUp.setSize(200,200);
		popUp.show(this,x,y);
		popUp.setVisible(true);
		
		
	}

	public void setStatus(int status) {
		this.state=status;
		
	}
}
